#include "StdAfx.h"
#include <algorithm>
#include <time.h>
#include <boost/regex.hpp>


static const boost::regex g_part("^(\\d+):\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)$");
static const boost::regex g_aggr("^(\\d+)$");
static const size_t g_signatureLength(6);

//////////////////////////////////////////////////////////////////////////
PartPtr Part::Create(const std::string& i_part, AggregatorPtr i_aggr)
{
   boost::smatch matches;
   if(boost::regex_match(i_part, matches, g_part))
   {
      try
      {
         Signature sign;
         for(int i = 2; i<=7;++i)
            sign.push_back(boost::lexical_cast<int>(matches[i]));
         PartPtr part(new Part(boost::lexical_cast<int>(matches[1]), sign));
         part->SetAggregator(i_aggr);
         return part;
      }
      catch(boost::bad_lexical_cast &)
      {
         return PartPtr();
      }
   }
   return PartPtr();
}

//////////////////////////////////////////////////////////////////////////
std::string Part::ToString() const
{
   std::ostringstream partStr;
   partStr << m_partID << ":";
   for (Signature::const_iterator it = m_sign.begin(); it != m_sign.end(); ++it)
   {
      partStr << " " << *it;
   }
   return partStr.str();
}

//////////////////////////////////////////////////////////////////////////
void Part::SetAggregator(AggregatorPtr i_aggr)
{
   m_aggr = i_aggr;
}

//////////////////////////////////////////////////////////////////////////
AggregatorPtr Part::GetAggregator() const
{
   return m_aggr.lock();
}

//////////////////////////////////////////////////////////////////////////
AggregatorPtr Aggregator::Create(const std::string& i_aggregator)
{
   boost::smatch matches;
   if(boost::regex_match(i_aggregator, matches, g_aggr))
   {
      try
      {
         return AggregatorPtr(new Aggregator(boost::lexical_cast<int>(matches[1])));
      }
      catch(boost::bad_lexical_cast &)
      {
         return AggregatorPtr();
      }  
   }
   return AggregatorPtr();
}

//////////////////////////////////////////////////////////////////////////
const PartsList& Aggregator::GetParts() const
{
	return m_parts;
}

//////////////////////////////////////////////////////////////////////////
std::string Aggregator::ToString() const
{
   std::ostringstream aggregator;
   aggregator << m_aggrID << std::endl;
   for (PartsList::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it)
   {
      aggregator << (*it)->ToString() << std::endl;
   }
   return aggregator.str();
}

//////////////////////////////////////////////////////////////////////////
void Aggregator::AddPart(PartPtr i_part)
{
   if (i_part.get()!= NULL)
   {
      m_parts.push_back(i_part);
   }
}